"""Particle renderers

A particle renderer instance is bound to a single group and is used to draw
that group's particles. How the particles in the group are drawn is completely
up to the renderer
"""
__version__ = '$Id$'

import particle_struct
import pyglet
import random, math
from pyglet import image
from pyglet.gl import *
import ctypes


class Renderer(object):
	"""Renderer base class"""

	group = None

	def set_group(self, group):
		"""Set the renderer's group"""
		if self.group is not None and self.group is not group:
			self.group.set_renderer(None)
		self.group = group
		# Subclasses may wish to extend this to reset state
	
	def draw(self):
		"""Render the group's particles"""
		raise NotImplementedError


class PointRenderer(Renderer):
	"""Simple renderer using GL_POINTS"""

	def __init__(self, size=1.0):
		self.size = size

	def draw(self):
		"""Render the particles as points"""
		glPointSize(self.size)
		glBegin(GL_POINTS)
		for p in self.group:
			#For first version of this I am going to draw using immediate mode, convert to arrays later
			glColor4f(*p.color)
			glVertex3f(*p.position)
		glEnd()

class FireRenderer(Renderer):
	"""Simple renderer using GL_POINTS"""

	def __init__(self, texture=None, size=1.0):
		self.size = size

		if texture is not None:
			self.load_texture(texture)

	def load_texture(self, file_or_texture):
		"""load the texture, which may be a file name or pyglet texture object
		"""
		if isinstance(file_or_texture, str):
			pic = image.load(file_or_texture)
			self.texture = pic.texture
		else:
			self.texture = file_or_texture

	def draw(self):
		"""Render the particles as texture mapped quads"""
		glEnable(self.texture.target)
		glBindTexture(self.texture.target, self.texture.id)
		#fade particles by random amount
		alpha_fade = random.randint(0,500)
		alpha_fade = (-(alpha_fade * .0002) -.01)

		for p in self.group:
				#For first version of this I am going to draw using immediate mode, convert to arrays later
			pos_x  = p.position.x
			pos_y  = p.position.y
			pos_z  = p.position.z
			width  = p.size.x
			height = p.size.y
			depth  = p.size.z	
			glBegin(GL_QUADS)
			glColor4f(*p.color)
			glTexCoord2f(1,1)
			glVertex3f(pos_x, pos_y + height, pos_z + depth)#Top left
			glTexCoord2f(0,1) 
			glVertex3f(pos_x + width, pos_y + height, pos_z + depth) #Top right
			glTexCoord2f(0,0)
			glVertex3f(pos_x, pos_y, pos_z) #Bottom right
			glTexCoord2f(1,0)
			glVertex3f(pos_x, pos_y, pos_z)#Bottom left
			glEnd()
			p.color.a+= alpha_fade

			
class TexturedRenderer(Renderer):
	"""Simple renderer using a texture"""

	def __init__(self, texture=None):
		"""initialize the renderer. 

		texture -- A file name, pyglet texture object
		"""
		if texture is not None:
			self.load_texture(texture)

	def load_texture(self, file_or_texture):
		"""load the texture, which may be a file name or pyglet texture object
		"""
		if isinstance(file_or_texture, str):
			pic = image.load(file_or_texture)
			self.texture = pic.texture
		else:
			self.texture = file_or_texture

	def draw(self):
		scaletext = 2.5
		glColor3f(1.0,0,0)
		glEnable(self.texture.target)
		glBindTexture(self.texture.target, self.texture.id)
		glTexParameteri(self.texture.target, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
		glTexParameteri(self.texture.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR)

		for p in self.group:
			#For first version of this I am going to draw using immediate mode, convert to arrays later
			position = p.position
			if position is not None:
				pos_x = position.x
				pos_y = position.y
				pos_z = position.z
				#glColor4f(self.particles[i].r,self.particles[i].g,self.particles[i].b,self.particles[i].life)
				glBegin(GL_TRIANGLE_STRIP)#Build Quad From A Triangle Strip
				glTexCoord2d(1,1)
				glVertex3f(pos_x+scaletext,pos_y+scaletext,pos_z)#Top Right
				glTexCoord2d(0,1)
				glVertex3f(pos_x-scaletext,pos_y+scaletext,pos_z)#Top Left
				glTexCoord2d(1,0)
				glVertex3f(pos_x+scaletext,pos_y-scaletext,pos_z)#Bottom Right
				glTexCoord2d(0,0)
				glVertex3f(pos_x-scaletext,pos_y-scaletext,pos_z)#Bottom Left
				glEnd()
				

